BUG_ON((bus > 255) || (dev > 31) || (func > 7) || (reg > 255));
pci_sal_write(0, bus, (dev<<3)|func, reg, 4, data);
}
+
+int pci_find_ext_capability(int seg, int bus, int devfn, int cap)
+{
+ return 0;
+}
return NULL;
}
+/**
+ * pci_enable_acs - enable ACS if hardware support it
+ * @dev: the PCI device
+ */
+void pci_enable_acs(struct pci_dev *pdev)
+{
+ int pos;
+ u16 cap;
+ u16 ctrl;
+
+ u8 bus = pdev->bus;
+ u8 dev = PCI_SLOT(pdev->devfn);
+ u8 func = PCI_FUNC(pdev->devfn);
+
+ if ( !iommu_enabled )
+ return;
+
+ pos = pci_find_ext_capability(0, bus, pdev->devfn, PCI_EXT_CAP_ID_ACS);
+ if (!pos)
+ return;
+
+ cap = pci_conf_read16(bus, dev, func, pos + PCI_ACS_CAP);
+ ctrl = pci_conf_read16(bus, dev, func, pos + PCI_ACS_CTRL);
+
+ /* Source Validation */
+ ctrl |= (cap & PCI_ACS_SV);
+
+ /* P2P Request Redirect */
+ ctrl |= (cap & PCI_ACS_RR);
+
+ /* P2P Completion Redirect */
+ ctrl |= (cap & PCI_ACS_CR);
+
+ /* Upstream Forwarding */
+ ctrl |= (cap & PCI_ACS_UF);
+
+ pci_conf_write16(bus, dev, func, pos + PCI_ACS_CTRL, ctrl);
+}
+
int pci_add_device(u8 bus, u8 devfn)
{
struct pci_dev *pdev;
goto out;
list_add(&pdev->domain_list, &dom0->arch.pdev_list);
+ pci_enable_acs(pdev);
}
out:
pdev->domain = d;
list_add(&pdev->domain_list, &d->arch.pdev_list);
domain_context_mapping(d, pdev->bus, pdev->devfn);
+ pci_enable_acs(pdev);
if ( ats_device(0, pdev->bus, pdev->devfn) )
enable_ats_device(0, pdev->bus, pdev->devfn);
}
int msixtbl_pt_register(struct domain *d, int pirq, uint64_t gtable);
void msixtbl_pt_unregister(struct domain *d, int pirq);
+void pci_enable_acs(struct pci_dev *pdev);
#endif /* __XEN_PCI_H__ */
#define PCI_EXT_CAP_ID_VC 2
#define PCI_EXT_CAP_ID_DSN 3
#define PCI_EXT_CAP_ID_PWR 4
-#define PCI_EXT_CAP_ID_ARI 0xE
-#define PCI_EXT_CAP_ID_ATS 0xF
-#define PCI_EXT_CAP_ID_IOV 0x10
+#define PCI_EXT_CAP_ID_ACS 13
+#define PCI_EXT_CAP_ID_ARI 14
+#define PCI_EXT_CAP_ID_ATS 15
+#define PCI_EXT_CAP_ID_IOV 16
/* Advanced Error Reporting */
#define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */
#define HT_CAPTYPE_GEN3 0xD0 /* Generation 3 hypertransport configuration */
#define HT_CAPTYPE_PM 0xE0 /* Hypertransport powermanagement configuration */
+/* Access Control Service */
+#define PCI_ACS_CAP 0x04 /* ACS Capability Register */
+#define PCI_ACS_SV 0x01 /* Source Validation */
+#define PCI_ACS_TB 0x02 /* Translation Blocking */
+#define PCI_ACS_RR 0x04 /* P2P Request Redirect */
+#define PCI_ACS_CR 0x08 /* P2P Completion Redirect */
+#define PCI_ACS_UF 0x10 /* Upstream Forwarding */
+#define PCI_ACS_EC 0x20 /* P2P Egress Control */
+#define PCI_ACS_DT 0x40 /* Direct Translated P2P */
+#define PCI_ACS_CTRL 0x06 /* ACS Control Register */
+#define PCI_ACS_EGRESS_CTL_V 0x08 /* ACS Egress Control Vector */
#endif /* LINUX_PCI_REGS_H */